
package com.kim.ping.Controller

import org.slf4j.LoggerFactory
import org.springframework.http.ResponseEntity
import org.springframework.web.client.RestTemplate
import spock.lang.Specification
import spock.lang.TempDir

class PingServiceImplSpec extends Specification {

    @TempDir
    File tempDir

    def logger = LoggerFactory.getLogger(PingServiceImplSpec.class)
    def restTemplate = Mock(RestTemplate)
    def pingService = new PingServiceImpl(restTemplate: restTemplate)

    def setup() {
        pingService.PONG_SERVICE_URL = "http://localhost:8082/pong"
        pingService.RATE_LIMIT_FILE_1 = new File(tempDir, "ping_rate_limiter_1.file")
        pingService.RATE_LIMIT_FILE_2 = new File(tempDir, "ping_rate_limiter_2.file")
    }

    def "sayHello should log and call Pong service when both locks are acquired"() {
        given:
        def trackingNumber = UUID.randomUUID().toString()
        def response = ResponseEntity.ok("World")

        when:
        pingService.sayHello()

        then:
        1 * restTemplate.getForEntity(pingService.PONG_SERVICE_URL, String.class) >> response
        logger.info(trackingNumber + ": resp:{}", "World")
    }

    def "sayHello should log and not call Pong service when both locks are not acquired"() {
        given:
        def trackingNumber = UUID.randomUUID().toString()

        when:
        pingService.sayHello()

        then:
        logger.info(trackingNumber + ": get fileLock 1 fail, try to get fileLock 2")
        logger.info(trackingNumber + ": get fileLock 2 fail")
        logger.info(trackingNumber + ": All file is lock, do nothing")
    }

    def "sayHello should log and call Pong service when only the first lock is acquired"() {
        given:
        def trackingNumber = UUID.randomUUID().toString()
        def response = ResponseEntity.ok("World")

        when:
        pingService.sayHello()

        then:
        1 * restTemplate.getForEntity(pingService.PONG_SERVICE_URL, String.class) >> response
        logger.info(trackingNumber + ": resp:{}", "World")
    }

    def "sayHello should log and call Pong service when only the second lock is acquired"() {
        given:
        def trackingNumber = UUID.randomUUID().toString()
        def response = ResponseEntity.ok("World")

        when:
        pingService.sayHello()

        then:
        1 * restTemplate.getForEntity(pingService.PONG_SERVICE_URL, String.class) >> response
        logger.info(trackingNumber + ": resp:{}", "World")
    }
}